/**
 * defineProperty
 * [description] 定义对象属性或者修改原有的属性
 */

(function(){
	const object = {};
	Object.defineProperty(object, 'name', {
		// value: '波仔',
		// writable: true, // 是否可写。默认false
		get(arg) {
			return this.set()
			console.log('get', this)
		},
		set: (arg) => {
			console.log('set', arg + 'asfasf')
			return arg
		}
	});
	setTimeout(function() {
		object.name = '1233123';
		console.log(object)
	}, 500)
})()

(function() {
	let obj = { name: '波仔', age: '18', sex: '男' },
	    defaultName = '';
	Object.keys(obj).forEach(key => {
	  Object.defineProperty(obj, key, { // 拦截整个object 对象，并通过get获取值，set设置值，vue 2.x的核心就是这个来监听
	    get(value) {
	      return 42323;
	    },
	    set(value) {
	      defaultName = value;
	      return value;
	    }
	  });
	});
	obj.name = "haha";
	console.log(defaultName); // haha
	console.log(obj.name); // 42323
})()

/**
 * 1、configurable
 * 		是否可删除
 * 		当且仅当该属性的 configurable 键值为 true 时，该属性的描述符才能够被改变，同时该属性也能从对应的对象上被删除。
 *    	默认为 false。
 *
 * 2、enumerable
 * 		是否可枚举
 * 	  	当且仅当该属性的 enumerable 键值为 true 时，该属性才会出现在对象的枚举属性中。	
 * 	   	在枚举对象属性时会被枚举到（for...in 或 Object.keys 方法），可以改变这些属性的值，也可以删除这些属性。
 * 	    默认为 false。
 *
 * 3、value
 * 		定义属性值
 * 		该属性对应的值。可以是任何有效的 JavaScript 值（数值，对象，函数等）。
 * 		默认为 undefined。
 *
 * 4、writable
 * 		是否可修改
 * 		当且仅当该属性的 writable 键值为 true 时，属性的值，也就是上面的 value，才能被赋值运算符改变。
 * 		默认为 false。
 *
 *	存取描述符还具有以下可选键值：
 * 
 * 	5、get
 * 	 	属性的 getter 函数，如果没有 getter，则为 undefined。当访问该属性时，会调用此函数。
 * 	 	执行时不传入任何参数，但是会传入 this 对象（由于继承关系，这里的this并不一定是定义该属性的对象）。
 * 	 	该函数的返回值会被用作属性的值。
 * 	 	默认为 undefined。
 *
 * 6、set
 * 		属性的 setter 函数，如果没有 setter，则为 undefined。当属性值被修改时，会调用此函
 * 		数。该方法接受一个参数（也就是被赋予的新值），会传入赋值时的 this 对象。
 * 		默认为 undefined。
 *
 *
 *
 *
 *
 *
 *
 * 
 */